package com.treetao.union.core.tencent.microapp;

import java.util.Map;

import org.springframework.stereotype.Component;

import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.google.common.collect.Maps;
import com.treetao.union.core.exception.DevMException;
import com.treetao.union.core.tencent.microapp.option.MicroappOption;
import com.treetao.union.core.util.RandomUtils;
import com.treetao.union.core.util.hex.MD5;

import lombok.extern.slf4j.Slf4j;

/**
 * 微信小程序支付相关服务
 * 
 * @author Dev.M
 *
 */
@Component
@Slf4j
public class TencentMicroappPayService {
	WxPayService service = new WxPayServiceImpl();

	public void config(MicroappOption option) {
		WxPayConfig config = new WxPayConfig();
		config.setAppId(option.getAppId());
		config.setMchId(option.getMchId());
		config.setMchKey(option.getMchKey());
		config.setNotifyUrl(option.getNotifyUrl());
		config.setTradeType(option.getTradeType());
		service.setConfig(config);
	}

	/**
	 * 统一下单
	 * 
	 * @param openid         用户OPENID
	 * @param outTradeNo     业务唯一订单号
	 * @param body           订单描述
	 * @param totalFee       支付金额（单位：分，最低一分）
	 * @param spbillCreateIp 用户当前IP
	 * @return
	 */
	public Map<String, Object> newOrder(String openid, String outTradeNo, String body, int totalFee,
			String spbillCreateIp) {
		WxPayUnifiedOrderRequest unifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder().outTradeNo(outTradeNo)
				.body(body).totalFee(totalFee).spbillCreateIp(spbillCreateIp).build();
		String nonceStr = RandomUtils.randomString(16);
		unifiedOrderRequest.setNonceStr(nonceStr);
		unifiedOrderRequest.setOpenid(openid);
		WxPayUnifiedOrderResult unifiedOrderResult = null;

		try {
			log.info("小程序统一下单请求 ：" + unifiedOrderRequest.toString());
			unifiedOrderResult = service.unifiedOrder(unifiedOrderRequest);
			log.info("小程序统一下单结果 ：" + unifiedOrderResult.toString());

			long seconds = System.currentTimeMillis() / 1000;
			String appid = service.getConfig().getAppId();

			String preMd5 = "appId=" + appid + "&nonceStr=" + nonceStr + "&package=prepay_id="
					+ unifiedOrderResult.getPrepayId() + "&signType=MD5&timeStamp=" + seconds + "&key="
					+ service.getConfig().getMchKey();
			log.info("待签名内容：" + preMd5);
			String paySign = MD5.digestByMd5(preMd5);

			Map<String, Object> result = Maps.newHashMap();
			result.put("timeStamp", String.valueOf(seconds));
			result.put("nonceStr", nonceStr);
			result.put("package", "prepay_id=" + unifiedOrderResult.getPrepayId());
			result.put("signType", "MD5");
			result.put("paySign", paySign);
			result.put("prepay_id", unifiedOrderResult.getPrepayId());

			return result;
		} catch (WxPayException e) {
			throw new DevMException(e.getReturnMsg()==null?e.getCustomErrorMsg():e.getReturnMsg());
		}
	}

	/**
	 * 支付通知结果验证并解析
	 * 
	 * @param xmlData
	 * @throws WxPayException 
	 */
	public WxPayOrderNotifyResult notifyCallbackParse(String xmlData) throws WxPayException {
		return service.parseOrderNotifyResult(xmlData);//已对结果进行验证了，如果错误代码，抛出异常了
	}

	/**
	 * 支付回调处理完成后，响应结果给微信
	 * 
	 * @param success
	 * @return
	 */
	public String genPayCallbackContent(boolean success) {
		if (success) {
			return "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
					+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
		} else {
			return "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
					+ "<return_msg><![CDATA[FAIL_MSG]]></return_msg>" + "</xml> ";
		}
	}
}
